package com.paishen.peiniwan;

import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.support.multidex.MultiDexApplication;
import android.text.TextUtils;
import android.util.FloatMath;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.bumptech.glide.Glide;
import com.google.gson.Gson;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.easeui.EaseConstant;
import com.hyphenate.easeui.controller.EaseUI;
import com.hyphenate.easeui.domain.EaseUser;
import com.hyphenate.exceptions.HyphenateException;
import com.paishen.common.LibCommon;
import com.paishen.common.cache.DiskLruCacheUtil;
import com.paishen.common.okhttp.OkHttpClientManager;
import com.paishen.common.util.BaseUtil;
import com.paishen.common.util.LogUtil;
import com.paishen.common.util.SpfsUtil;
import com.paishen.libamap.poisearch.AMapUtil;
import com.paishen.peiniwan.database.DaoMaster;
import com.paishen.peiniwan.database.DaoSession;
import com.paishen.peiniwan.database.User;
import com.paishen.peiniwan.database.UserDao;
import com.paishen.peiniwan.database.util.ModelConverter;
import com.paishen.peiniwan.frame.PnwOkCallbackAdapter;
import com.paishen.peiniwan.frame.http.HttpResp;
import com.paishen.peiniwan.frame.http.PnwHttpManager;
import com.paishen.peiniwan.frame.http.response.HttpRespUsers;
import com.paishen.peiniwan.frame.push.PushController;
import com.squareup.okhttp.Request;
import com.umeng.analytics.MobclickAgent;
import com.umeng.socialize.PlatformConfig;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

import cn.jpush.android.api.JPushInterface;
import de.greenrobot.event.EventBus;
import jp.wasabeef.glide.transformations.CropCircleTransformation;


public class App extends MultiDexApplication {

    private static App instance;
    private CropCircleTransformation cctf;

    private Gson gson;
    private DaoMaster.DevOpenHelper dbHelper;
    private DaoSession daoSession;
    private com.paishen.peiniwan.database.User user;
    private final Handler mDelivery = new Handler(Looper.getMainLooper());
    private DiskLruCacheUtil slcu;
    private long dbOpenedUserId;
    private String userAgent = "";

    public static final boolean DEBUG_MODE = true;

    @Override
    public void onCreate() {
        super.onCreate();
        LogUtil.d("App onCreate()");
        instance = this;

        PlatformConfig.setWeixin("wxa0937aa7ed498299", "a7a45476136b9fc4da27806c21c69b6e");
        PlatformConfig.setSinaWeibo("6358528", "14de7375f282ebadc7215bf2f445050f");
        PlatformConfig.setQQZone("1105134774", "OvvOLsuPpi72Tiz1");

        // this function will initialize the HuanXin SDK

        EMOptions emOptions = new EMOptions();
        emOptions.setAutoLogin(false);
        // 默认添加好友时，是不需要验证的，改成需要验证
        emOptions.setAcceptInvitationAlways(false);
        // 设置是否需要已读回执
        emOptions.setRequireAck(true);
        // 设置是否需要已送达回执
        emOptions.setRequireDeliveryAck(false);
        // 设置从db初始化加载时, 每个conversation需要加载msg的个数
        emOptions.setNumberOfMessagesLoaded(1);
        if (EaseUI.getInstance().init(this, emOptions)) {
            EaseUI.getInstance().setUserProfileProvider(new EaseUI.EaseUserProfileProvider() {
                @Override
                public EaseUser getUser(String username) {
                    if (username != null) {
                        UserDao userDao = getCurrDaoSession().getUserDao();
                        LogUtil.t("EaseUI UserProfileProvider getEasemob :" + username);
                        com.paishen.peiniwan.database.User dbUser = userDao.queryBuilder().where(UserDao.Properties.Easemob_username.eq(username)).unique();
                        if (dbUser != null && !TextUtils.isEmpty(dbUser.getNickname()) && !TextUtils.isEmpty(dbUser.getHead_img_url())) {
                            EaseUser easeUser = new EaseUser(username);
                            easeUser.setNick(dbUser.getNickname());
                            easeUser.setAvatar(dbUser.getHead_img_url());
                            return easeUser;
                        } else {
                            // username
                            PnwHttpManager.User.getUserByEasemob("App", new String[]{username}, new PnwOkCallbackAdapter<HttpRespUsers<List<com.paishen.peiniwan.frame.http.entity.User>>>() {
                                @Override
                                public void onResponse(HttpRespUsers<List<com.paishen.peiniwan.frame.http.entity.User>> response, boolean fresh) {
                                    super.onResponse(response, fresh);
                                    if (response.errcode == C.http.RESULT_SUCCESS) {
                                        com.paishen.peiniwan.frame.http.entity.User target = response.users.get(0);
                                        final UserDao userDao = App.i().getCurrDaoSession().getUserDao();
                                        com.paishen.peiniwan.database.User dbTarget = ModelConverter.mergeOrReplace(null, response.users.get(0));
                                        dbTarget.setNickname(target.nickname);
                                        dbTarget.setHead_img_url(target.head_img_url);
                                        userDao.insertOrReplace(dbTarget);

                                        EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_MAIN_MESSAGE_RESET_NICK));
                                    }
                                }

                                @Override
                                public void onFailure(Request request, Exception e) {
                                    //
                                }
                            });
                        }
                    }
                    return null;
                }
            });
//            EMClient.getInstance().chatManager()..registerEventListener(new EMEventListener() {
//                                                                  @Override
//                                                                  public void onEvent(final EMNotifierEvent emNotifierEvent) {
//                                                                      mDelivery.post(new Runnable() {
//                                                                          @Override
//                                                                          public void run() {
//                                                                              EMMessage message = (EMMessage) emNotifierEvent.getData();
//                                                                              EaseUI.getInstance().getNotifier().onNewMsg(message);
//                                                                          }
//                                                                      });
//
//                                                                      EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_MAIN_MESSAGE_NEW_MESSAGE));
//                                                                  }
//                                                              },
//                    new EMNotifierEvent.Event[]{EMNotifierEvent.Event.EventNewMessage});

            EMClient.getInstance().chatManager().addMessageListener(new EMMessageListener() {
                @Override
                public void onMessageReceived(List<EMMessage> list) {
                    if (list != null && list.size() > 0) {
                        final EMMessage message = list.get(list.size() - 1);
                        mDelivery.post(new Runnable() {
                            @Override
                            public void run() {
                                EaseUI.getInstance().getNotifier().onNewMsg(message);
                            }
                        });

                        try {
                            String mType = message.getStringAttribute(EaseConstant.TYPE);
                            if (TextUtils.equals(mType, EaseConstant.TYPE_GIFT)) {
                                int value = Integer.parseInt(message.getStringAttribute(EaseConstant.PARAMS_VALUE));
                                if (user != null) {
                                    user.setAmount(user.getAmount() + value);
                                    EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_EASE_NEW_GIFT));
                                }
                            }
                        } catch (Exception e) {
                        }

                        EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_MAIN_MESSAGE_NEW_MESSAGE));
                    }
                }

                @Override
                public void onCmdMessageReceived(List<EMMessage> list) {
                }

                @Override
                public void onMessageReadAckReceived(List<EMMessage> list) {
                }

                @Override
                public void onMessageDeliveryAckReceived(List<EMMessage> list) {
                }

                @Override
                public void onMessageChanged(EMMessage emMessage, Object o) {
                }
            });


            EMClient.getInstance().setDebugMode(DEBUG_MODE);
        }

        /**
         * 使用集成测试服务（推荐）
         * 集成测试是通过收集和展示已注册测试设备发送的日志，来检验SDK集成有效性和完整性的一个服务
         * 所有由注册设备发送的应用日志将实时地进行展示
         * 你可以方便地查看包括应用版本、渠道名称、自定义事件、页面访问情况等数据，提升集成与调试的工作效率
         * 所有测试数据不会进入应用正式的统计后台，而只是展示在测试的数据报表中
         * 你不必再担心因为测试而导致的数据污染问题，让数据更加真实有效的反应用户使用情况。
         * 使用集成测试模式请先在程序入口处调用如下代码，打开调试模式
         */
        MobclickAgent.setDebugMode(DEBUG_MODE);

        JPushInterface.setDebugMode(DEBUG_MODE);    // 设置开启日志,发布时请关闭日志 [混淆崩溃]
        JPushInterface.init(this);             // 初始化 JPush

        LibCommon.init(this);
        LibCommon.setDebugMode(true, "peiniwan");

        PushController.getInstance().init(this);

        OkHttpClientManager.getInstance().init(this, userAgent = BaseUtil.getDeviceInfo(), DEBUG_MODE);


        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {
                ex.printStackTrace();
                try {
                    Thread.sleep(800);
                } catch (InterruptedException e) {
                }
                ActivityCollector.finishAll();
                System.exit(0);
            }
        });

        EventBus.getDefault().register(this);
    }


    public DaoSession getCurrDaoSession() {
        if (getUser() != null) {
            return getDaoSession(getUser().getId());
        }
        return null;
    }

    public DaoSession getDaoSession(long uid) {
        if (dbHelper != null && uid != dbOpenedUserId) {
            if (daoSession != null) {
                daoSession.clear();
                daoSession = null;
            }
            dbHelper.close();
            dbHelper = null;
        }

        if (dbHelper == null || daoSession == null) {
            dbHelper = new DaoMaster.DevOpenHelper(this, "db_" + uid, null);
            DaoMaster daoMaster = new DaoMaster(dbHelper.getWritableDatabase());
            daoSession = daoMaster.newSession();
            dbOpenedUserId = uid;
        }
        return daoSession;
    }

    public static synchronized App i() {
        return instance;
    }

    // 更新位置信息
    public void locationAsync(final PnwOkCallbackAdapter<HttpResp> callbackAdapter) {
        if (user != null) {
            AMapUtil.asyncLoc(this, new AMapLocationListener() {
                @Override
                public void onLocationChanged(final AMapLocation aMapLocation) {
                    if (aMapLocation == null || aMapLocation.getLatitude() * aMapLocation.getLongitude() == 0) {
                        // 定位失败
                        callbackAdapter.onFailure(null, null);
                        return;
                    }

                    if (user != null) {
                        SpfsUtil.write(C.sp.LAT, aMapLocation.getLatitude());
                        SpfsUtil.write(C.sp.LNG, aMapLocation.getLongitude());
                        PnwHttpManager.User.updateLandmark("App", aMapLocation.getLatitude(), aMapLocation.getLongitude(), callbackAdapter);
                    }
                }
            });
        }
    }

    public void locationAsync() {
        locationAsync(new PnwOkCallbackAdapter<HttpResp>() {
            @Override
            public void onFailure(Request request, Exception e) {
            }
        });
    }

    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }

    public String getJPushRegistrationId() {
        return JPushInterface.getRegistrationID(this);
    }

    public String getUserAgent() {
        return userAgent;
    }

    public Gson getGson() {
        return gson != null ? gson : (gson = new Gson());
    }


    public DiskLruCacheUtil getHttpCacheUtil() {
        return slcu != null ? slcu : (slcu = DiskLruCacheUtil.open(this, "http"));
    }

    public CropCircleTransformation getCropCircleTransformation() {
        return cctf != null ? cctf : (cctf = new CropCircleTransformation(this));
    }

    public void onEventBackgroundThread(com.paishen.peiniwan.BusEvent event) {
        if (event.type == BusEvent.TYPE_BACKGROUND) {
            switch (event.action) {
                case BusEvent.ACTION_SETTINGS_CLEAR_CACHE:
                    LogUtil.d("ACTION_SETTINGS_CLEAR_CACHE");
                    Glide.get(this).clearDiskCache();
                    break;
                case BusEvent.ACTION_DB_UPDATE_USER:
                    LogUtil.d("ACTION_DB_UPDATE_USER");
                    User updateTarget = (User) event.content;
                    if (updateTarget != null) {
                        UserDao userDao = App.i().getCurrDaoSession().getUserDao();
                        userDao.insertOrReplace(updateTarget);
                    }
                    break;
            }
        }
    }

}
